#!/usr/bin/env bash

# 引入外部脚本
. "${LINUX_TOOLS_DIR}/utils/utils.sh"

function echo_split() {
  echo -e "\033[36m-----------------------------------------------------------\033[0m"
}

# 系统基本信息-主菜单显示
function os_info_main() {

  local hostName=$(uname -n)                                                                         # 主机名称
  local operatingSystem=$(hostnamectl | grep Operating | awk -F : '{print $2}' | sed 's/^[ \t]*//g') # 操作系统
  local kernel=$(uname -srm)                                                                         # 系统语言环境
  local osDate=$(date +%F_%T)                                                                        # 系统时间
  local bashVersion=$(bash --version | grep "GNU bash" | awk '{print $4}')                           # Shell 版本
  local osUpdate=$(uptime | awk -F',' '{sub(/.*up /,"",$1);print $1}')                               # 系统运行时间
  local dockerVersion=$(docker -v | awk '{print $3}' | sed 's/,//')                               # 系统运行时间

  echo -e "\t主机名称: ${hostName}"
  echo -e "\t操作系统: ${operatingSystem}"
  echo -e "\t系统内核: ${kernel}"
  echo -e "\t系统时间: ${osDate}"
  echo -e "\t本机 IP: ${ipaddr}"
  echo -e "\tShell版本: ${bashVersion}"
  echo -e "\tDocker版本: ${dockerVersion}"
}


# 系统基本信息
function os_info() {

  local hostName=$(uname -n)                                                                         # 主机名称
  local operatingSystem=$(hostnamectl | grep Operating | awk -F : '{print $2}' | sed 's/^[ \t]*//g') # 操作系统
  local kernel=$(uname -srm)                                                                         # 系统内核
  local osLang=$(echo $LANG)                                                                         # 系统语言环境
  local osDate=$(date +%F_%T)                                                                        # 系统时间
  local bashVersion=$(bash --version | grep "GNU bash" | awk '{print $4}')                           # Shell 版本
  local osUpdate=$(uptime | awk -F',' '{sub(/.*up /,"",$1);print $1}')                               # 系统运行时间
  local osLastReboot=$(last reboot | head -1 | awk '{print $5,$6,$7,$8,$10}')                        # 系统上次重启时间
  local osLastShutdown=$(last -x | grep shutdown | head -1 | awk '{print $5,$6,$7,$8,$10}')          # 系统上次关机时间
  local ipaddr=$(hostname -I)                                                                        # 系统上次关机时间

  echo_split
  echo_blue "系统基本信息-SystemInfo"
  echo -e "\t主机名称: ${hostName}"
  echo -e "\t操作系统: ${operatingSystem}"
  echo -e "\t系统内核: ${kernel}"
  echo -e "\t语言环境: ${osLang}"
  echo -e "\t系统时间: ${osDate}"
  echo -e "\t本机 IP: ${ipaddr}"
  echo -e "\tShell版本: ${bashVersion}"
  echo -e "\t已运行时间: ${osUpdate:-获取信息失败-fail}"
  echo -e "\t上次重启时间: ${osLastReboot:-获取信息失败-fail}"
  echo -e "\t上次关机时间: ${osLastShutdown:-获取信息失败-fail}"
}

# cpu基本信息
function cpu_info() {

  local cpuArch=$(uname -m)                                                                                    # CPU架构
  local cpuType=$(cat /proc/cpuinfo | grep "model name" | uniq | awk -F':' '{sub(/ /,"",$2);print $2}')        # CPU型号
  local cpuNum=$(cat /proc/cpuinfo | grep "physical id" | sort | uniq | wc -l)                                 # CPU个数
  local cpuCore=$(cat /proc/cpuinfo | grep cores | uniq | awk -F':' '{sub(/ /,"",$2);print $2}')               # CPU 核数
  local cpuHz=$(cat /proc/cpuinfo | grep "cpu MHz" | uniq | awk -F':' '{sub(/ /,"",$2);printf "%s MHz\n",$2}') # CPU 频率

  echo_split
  echo_blue "CPU基本信息-cpuInfo"
  echo -e "\tCPU型号：${cpuType}"
  echo -e "\tCPU架构：${cpuArch}"
  echo -e "\tCPU个数：${cpuNum}"
  echo -e "\tCPU核数: ${cpuCore}"
  echo -e "\tCPU频率：${cpuHz}"

  local cpuStatus=$(top -b -n 1 | head | grep "%Cpu(s)" | cut -d : -f 2 | sed 's/^[ \t]*//g') # cpu状态
  local userCpu=$(echo "${cpuStatus}" | awk -F ',' '{print $1}')                              # 用户空间占用CPU
  local kernelCpus=$(echo "${cpuStatus}" | awk -F ',' '{print $2}' | sed 's/^[ \t]*//g')      # 内核空间占用CPU
  local processCpus=$(echo "${cpuStatus}" | awk -F ',' '{print $3}' | sed 's/^[ \t]*//g')     # 改变过优先级的进程
  local freeCpus=$(echo "${cpuStatus}" | awk -F ',' '{print $4}' | sed 's/^[ \t]*//g')        # 空闲CPU百分比
  local ioWait=$(echo "${cpuStatus}" | awk -F ',' '{print $5}' | sed 's/^[ \t]*//g')          # IO等待占用CPU的百分比
  local hardware=$(echo "${cpuStatus}" | awk -F ',' '{print $6}' | sed 's/^[ \t]*//g')        # 硬中断
  local interrupts=$(echo "${cpuStatus}" | awk -F ',' '{print $7}' | sed 's/^[ \t]*//g')      # 软中断
  local real=$(echo "${cpuStatus}" | awk -F ',' '{print $7}' | sed 's/^[ \t]*//g')            # 等待真实的cpu资源

  echo_blue "CPU使用状态(%)百分比-cpuStatus(%)"
  echo -e "\t用户空间占用CPU: ${userCpu}"
  echo -e "\t内核空间占用CPU: ${kernelCpus}"
  echo -e "\t改变过优先级的进程: ${processCpus}"
  echo -e "\t空闲CPU百分比: ${freeCpus}"
  echo -e "\tIO等待占用CPU的百分比: ${ioWait}"
  echo -e "\t硬中断: ${hardware}"
  echo -e "\t软中断: ${interrupts}"
  echo -e "\t等待真实的cpu资源: ${real}"

}
# 内存基本信息
function mem_info() {

  local memTotal="$(($(grep MemTotal /proc/meminfo | awk '{print $2}') / 1024))"                                         # 内存总容量(MB)
  local memAvailable="$(($(grep -i Cached /proc/meminfo | awk '{print $2}' | head -1) / 1024))"                          # 程序认为可用内存(MB)
  local memFree="$(($(grep MemFree /proc/meminfo | awk '{print $2}') / 1024))"                                           # 内存剩余(MB)
  local memUsed=$((memTotal - memFree))                                                                                  # 已使用内存(MB)
  local memUsedPercent="$(awk "BEGIN {if(${memTotal}==0){printf 100}else{printf \"%.2f\",${memUsed}*100/${memTotal}}}")" # 内存使用率%

  echo_split
  echo_blue "内存基本信息-memInfo"
  echo -e "\t内存总量：${memTotal}MB"
  echo -e "\t已使用内存：${memUsed}MB"
  echo -e "\t内存使用率: ${memUsedPercent}%"
  echo -e "\t实际尚未使用: ${memFree}MB+${memAvailable}MB=${memFree}MB"
  echo -e "\t程序认为可用内存：${memAvailable}MB"

  local swapTotal="$(($(grep SwapTotal /proc/meminfo | awk '{print $2}') / 1024))"                                          # swap总容量(MB)
  local swapFree="$(($(grep SwapFree /proc/meminfo | awk '{print $2}') / 1024))"                                            # swap剩余量(MB)
  local memUsed=$((swapTotal - swapFree))                                                                                   # swap已使用量(MB)
  local swapUsedPercent="$(awk "BEGIN {if(${swapTotal}==0){printf 100}else{printf \"%.2f\",${memUsed}*100/${swapTotal}}}")" # swap使用率(MB)
  local swapPiness="$(cat /proc/sys/vm/swappiness)"                                                                         # swap权重

  echo_blue "内存基本信息-swapInfo"
  echo -e "\tSwap交换分区总量: ${swapTotal}MB"
  echo -e "\t交换分区使用量: ${memUsed}MB"
  echo -e "\t交换分区剩余量: ${swapFree}MB"
  echo -e "\t交换分区使用率: ${swapUsedPercent}%"
  echo -e "\t交换分区权重: ${swapPiness}%"
}

# 硬盘基本信息
function disk_info() {
  # 硬盘名称
  local diskInfo=$(blkid | awk -F':' '{print $1}' | grep -v sr0)
  for i in ${diskInfo}; do
    local diskName[${#diskName[*]}]=$i
  done
  # 硬盘类型
  local diskTypeInfo=$(blkid | awk '{print $1""$NF}' | grep -v sr0 | awk -F'"' '{print $2}')
  for i in ${diskTypeInfo}; do
    local diskType[${#diskType[*]}]=$i
  done
  # 硬盘大小
  local num=$(($(echo ${#diskName[*]}) - 1))
  for size in $(seq 0 ${num}); do
    local diskSizeArray=$(fdisk -l ${diskName[size]} | grep Disk | awk '{print $3""$4}' | cut -d , -f 1)
    local diskSize[${#diskSize[*]}]=$diskSizeArray
    local diskReadWritArray=$(iostat -d -x ${diskName[size]} | grep -v "^$" | tail -1 | awk '{print $4"\t"$5"\t"$6}')
    local diskReadWrit[${#diskReadWrit[*]}]=${diskReadWritArray}
  done

  echo_split
  echo_blue "硬盘基本信息-diskInfo"

  printf "\e[34m%-30s %-13s %-10s%-10s%-10s%-11s\e[0m\n" 名称 大小 r/s w/s rkB/s 类型
  for i in $(seq 0 $num); do
    printf "\e[32m%-28s %-10s  %-10s%-10s%-10s%-10s\e[0m\n" ${diskName[i]} ${diskSize[i]} ${diskReadWrit[i]} ${diskType[i]}
  done

}
#网络信息
function network_info() {
  local ip=$(hostname -I)                                                                                              # 系统IP
  local gateway=$(ip route | grep default &>/dev/null && ip route | grep default | awk '{print $3}' || echo '未设置默认网关') # 网关地址
  local dns=($(cat /etc/resolv.conf | grep nameserver | uniq | awk '{print $2}'))                                      # DNS地址

  echo_split
  echo_blue "网络基本信息-networkInfo"

  echo -e "\tIP地址：${ip}"
  echo -e "\tDNS地址：${dns[@]}"
  for i in $gateway; do
    echo -e "\t网关地址：${i}"
    echo -e "\t网关[${i}]连接情况: $(ping -t 1 -i 1 -c 5 -W 1 ${i} &>/dev/null && echo '正常通信' || echo '无法通信')"
  done
}

#网卡信息
function network_card_info() {
  local ifs=$(ifconfig | egrep "^[a-z]" | egrep -v "^c|^v" | awk -F ':' '{print $1}')

  local a=${ifs}
  local b=$(for i in $a; do echo $(ifconfig ${i} | grep inet6 | awk '{print $2}'); done)
  local ipv4=$(for i in $a; do echo "$(ifconfig ${i} | awk 'NR==2{print $2}')"; done)
  local netmask=$(for i in $a; do echo $(ifconfig $i | grep netmask | awk '{print $4}'); done)
  local broadcast=$(for i in $a; do echo $(ifconfig $i | grep broadcast | awk '{print $6}'); done)
  local RX_packets=$(for i in $a; do echo $(ifconfig $i | grep "RX packets" | awk -F '(' '{print $2}' | cut -d ")" -f 1 | awk '{print $1}'); done)
  local TX_packets=$(for i in $a; do echo $(ifconfig $i | grep "TX packets" | awk -F '(' '{print $2}' | cut -d ")" -f 1 | awk '{print $1}'); done)
  local num=$(for i in ${ifs}; do echo $i; done | wc -l)
  local num_01=$(for ((i = 0; i < $num; i++)); do echo $i; done)
  #ipv4
  for i in $ipv4; do network_ipv4[${#network_ipv4[*]}]=$i; done
  #ipv6
  for i in $b; do network_ipv6[${#network_ipv6[*]}]=$i; done
  #网卡名
  eth_name=($(echo ${ifs}))
  #netmask 子网掩码
  for i in $netmask; do network_netmask[${#network_netmask[*]}]=$i; done
  #broadcast 默认网关
  for i in $broadcast; do network_broadcast[${#network_broadcast[*]}]=$i; done
  #RX packets 出流量
  for i in $RX_packets; do network_RX_packets[${#network_RX_packets[*]}]=$i; done
  #TX packets 进流量
  for i in $TX_packets; do network_TX_packets[${#network_TX_packets[*]}]=$i; done

  echo_split
  echo_blue "网卡基本信息-networkCardInfo"

  printf "\e[34m%-17s %-15s %-17s %-15s %-10s %-15s %-23s\e[0m\n" 网卡 IPV4 掩码 广播 接收数据包 发送数据包 IPV6

  for i in $num_01; do
    if [ ${eth_name[i]} == lo ] || [ ${eth_name[i]} == tunl0 ]; then
      printf "%-15s %-15s %-31s %-10s %-10s %-15s %-23s\n" ${eth_name[i]} ${network_ipv4[i]} ${network_netmask[i]} ${network_RX_packets[i]} ${network_TX_packets[i]} ${network_ipv6[i]}
    else
      printf "%-15s %-15s %-15s %-15s %-10s %-15s %-23s\n" ${eth_name[i]} ${network_ipv4[i]} ${network_netmask[i]} ${network_broadcast[i]} ${network_RX_packets[i]} ${network_TX_packets[i]} ${network_ipv6[i]}
    fi
  done
}
# 系统资源信息
function resource_info() {
  # 当前进程数
  local CPU_PROCESSORS=$(top -d 1 -n 1 -b | awk 'NR==2{print $2}')
  # 当前正在运行进程数
  local CPU_RUN_PROCESSORS=$(top -d 1 -n 1 -b | awk 'NR==2{print $4}')
  # 当前正在休眠进程数
  local CPU_SL_PROCESSORS=$(top -d 1 -n 1 -b | awk 'NR==2{print $6}')
  # 当前停止运行进程数
  local CPU_STOP_PROCESSORS=$(top -d 1 -n 1 -b | awk 'NR==2{print 8}')
  # 当前僵尸进程数
  local CPU_ZOM_PROCESSORS=$(top -d 1 -n 1 -b | awk 'NR==2{print $10}')

  echo_split
  echo_blue "CPU使用率前十进程信息"
  echo "$(ps -eo user,pid,pcpu,pmem,args --sort=-pcpu | head -n 10)"

  echo_split
  echo_blue "\n内存使用率前十进程信息:"
  echo "$(ps -eo user,pid,pcpu,pmem,args --sort=-pmem | head -n 10)"

  echo_split
  echo_blue "\n系统磁盘分区inode使用情况："
  echo "$(df -Thi)"

  echo_split
  echo "系统当前进程数：$CPU_PROCESSORS"
  echo "系统当前进程运行数：$CPU_RUN_PROCESSORS"
  echo "系统当前休眠进程数：$CPU_SL_PROCESSORS"
  echo "系统当前停止进程数：$CPU_STOP_PROCESSORS"
  echo "系统当前僵尸进程数：$CPU_ZOM_PROCESSORS"

  echo_split
  echo "系统当前允许最大fd数量：$(cat /proc/sys/fs/file-nr | awk '{print $3}')"
  echo "系统当前已打开fd数量：$(cat /proc/sys/fs/file-nr | awk '{print $1}')"
  echo "系统单个进程运行打开fd数量：$(ulimit -n)"

  echo_split
  echo "系统当前socket连接数：$(netstat -anp &>/dev/null && netstat -anp | wc -l || echo 'net-tools 未安装,获取信息失败')"
  echo "系统 established socket数量: $(netstat -anp &>/dev/null && netstat -anp | grep "ESTABLISHED" | wc -l || echo 'net-tools 未安装,获取信息失败')"
  echo "系统 sync socket数量：$(netstat -anp &>/dev/null && netstat -anp | grep "SYN" | wc -l || echo 'net-tools 未安装,获取信息失败')"
  echo "系统当前已建立socket如下:"
  echo "$(netstat -anp &>/dev/null && netstat -anp | grep ESTABLISHED | awk '{printf "  本地:%-20s <=>    外部:%-22s\n",$4,$5}' || echo '')"
}

# 检查基础命令是否安装
function check_system_command() {
  local flag="0"
  for i in ifconfig blkid iostat; do
    if [[ "" == $(command -v $i) ]]; then
      echo_red "检测到 ${i} 未安装"
      flag="1"
    fi
  done

  if [ $flag == "1" ]; then
    read -r -p "如不安装部分信息会无法显示,是否安装(y|n): " input
    case $input in
    [yY][eE][sS] | [yY])
      flag="2"
      ;;
    *) ;;

    esac
  fi

  if [ ${flag} == "2" ]; then
    if [[ "" == $(command -v ifconfig) ]]; then
      install_soft net-tools
    fi
    if [[ "" == $(command -v blkid) ]] || [[ "" == $(command -v iostat) ]]; then
      install_soft sysstat
    fi
  fi

}

#系统信息
function system_info() {

  check_system_command # 检查基础命令是否安装
  os_info              #系统信息
  cpu_info             #cpu信息 状态
  mem_info             #内存信息 swap
  disk_info            #磁盘信息
  network_info         #网络信息
  network_card_info    #网卡信息
  resource_info        #系统资源

}
